package com.lagou.edu.support;

import com.alibaba.druid.util.StringUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.util.List;

/**
 * @author xgf
 */
public class CustomClassPathXmlApplicationContext {
    private String xmlPath;

    public CustomClassPathXmlApplicationContext(String xmlPath) {
        this.xmlPath = xmlPath;
    }

    public Object getBean(String beanID) throws Exception {
        if (StringUtils.isEmpty(beanID)) {
            throw new Exception("beanID不能为空！");
        }
        //1.解析xml文件 获取所有Bean节点信息
        List<Element> readXML = readXML();
        if (readXML == null) {
            throw new Exception("配置文件中，没有配置Bean信息！");
        }
        //2.使用方法参数beanID ，查找已经解析的xml配置文件的id信息是否一致
        String xmlBeanClass = findElementClassByReadXML(readXML, beanID);
        if (StringUtils.isEmpty(xmlBeanClass)) {
            throw new Exception("该bean对象没有配置class地址");
        }
        //3.通过反射解析对象
        return newInstance(xmlBeanClass);
    }

    //
    private String findElementClassByReadXML(List<Element> readXML, String beanID) throws Exception {
        for (Element element : readXML) {
            String xmlBeanID = element.attributeValue("id");
            if (StringUtils.isEmpty(xmlBeanID)) {
                continue;
            }
            //找到对应的ID，获取该bean的类名
            if (xmlBeanID.equals(beanID)) {
                String xmlBeanClass = element.attributeValue("class");
                return xmlBeanClass;
            }
        }
        return null;

    }

    //解析xml文件
    private List<Element> readXML() throws Exception {
        //1.读取xml文件
        SAXReader saxReader = new SAXReader();
        InputStream inputStream = getClassPath(xmlPath);
        Document document = saxReader.read(inputStream);
        //2.读取根节点
        Element rootElement = document.getRootElement();
        //3.获取根节点下面的所有子节点
        List elements = rootElement.elements();
        return elements;

    }

    //获取上下文路径
    private InputStream getClassPath(String xmlPath) throws Exception {
        InputStream inputStream = getClass().getClassLoader().getResourceAsStream(xmlPath);
        return inputStream;
    }

    //通过反射解析对象
    private Object newInstance(String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        Class<?> name = Class.forName(className);
        return name.newInstance();
    }
}
